package com.atldy.commerce.async.impl;

import cn.hutool.json.JSONUtil;
import com.atldy.commerce.enums.AsyncTaskStatus;
import com.atldy.commerce.vo.AsyncTaskInfo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @version 1.0
 * @Author: li-dong-yang
 * @CreateTime: 2021-08-20 12:48
 * @Description： 任务管理器切面 环绕
 */
@Component
@Slf4j
@Aspect
public class AsyncTaskMonitor {

    @Autowired
    private AsyncTaskManager asyncTaskManager;


    @Pointcut("execution( * com.atldy.commerce.async.impl.AsyncServiceImpl.*(..))")
    public void pointcutAround() {
    }

    /**
     * 切面环绕通知，记录任务状态
     */
    @Around("pointcutAround()")
    public Object taskHandlerAround(ProceedingJoinPoint joinPoint) {
        // TODO: 2021/8/20  前置通知
        //    获取参数
        String taskId = joinPoint.getArgs()[1].toString();
        AsyncTaskInfo asyncTaskInfo = asyncTaskManager.getAsyncTaskInfo(taskId);
        log.info("task info [{}]", JSONUtil.toJsonStr(asyncTaskInfo));
        //重置状态信息
        asyncTaskInfo.setStatus(AsyncTaskStatus.RUNNING);
        AsyncTaskStatus status;
        Object result;
        try {
            // 执行异步任务
            result = joinPoint.proceed();
            status = AsyncTaskStatus.SUCCESS;
        } catch (Throwable ex) {
            // 异步任务出现了异常
            result = null;
            status = AsyncTaskStatus.FAILED;
            log.error("AsyncTaskMonitor: async task [{}] is failed, Error Info: [{}]",
                    taskId, ex.getMessage(), ex);
        }
        asyncTaskInfo.setEndTime(new Date());
        asyncTaskInfo.setStatus(status);
        asyncTaskInfo.setTotalTime(String.valueOf(
                asyncTaskInfo.getEndTime().getTime() - asyncTaskInfo.getStartTime().getTime()
        ));
        asyncTaskManager.setAsyncTaskInfo(asyncTaskInfo);
        return result;
    }

}